// ==UserScript==
// @name				HWM - Mercenary Guild
// @namespace			figey_hwm_
// @description			Auto complete MG quest, give up the cargo
// @version				0.1.4
// @run-at				document-end
// @grant				GM_deleteValue
// @grant				GM_getValue
// @grant				GM_info
// @grant				GM_listValues
// @grant				GM_notification
// @grant				GM_setValue
// @noframe
// @require				https://notabug.org/figey/localDataStorage/raw/8018b121fb20340d325f45999a308b02b8d761e1/localDataStorage-1.2.0.trim.js
// @require				https://notabug.org/figey/hwm_scripts/raw/59e98a179ba73cc408884238fa4c7c0285622194/src/core.js
// @include				/^https?:\/\/(www\.)?(heroeswm\.ru|lordswm\.com)\/home\.php.*/
// @include				/^https?:\/\/(www\.)?(heroeswm\.ru|lordswm\.com)\/map\.php.*/
// @include				/^https?:\/\/(www\.)?(heroeswm\.ru|lordswm\.com)\/mercenary_guild\.php.*/
// ==/UserScript==

/**
 * TODO
 * autoskip unwanted tasks
 */

'use strict';

/**
 * Script settings
 */
const scriptSettings = {
	'mg_autocomplete': { name: 'Автосдача заданий', value: false, type: 'checkbox' },
	'mg_autocargo': { name: 'Авто отдача груза', value: false, type: 'checkbox' },
	'mg_skip' : {
		name: 'Пропускать задания(0=выкл)',
		value: {
			army: { name: 'Армии', level: 0, type: 'number' },
			invader: { name: 'Захватчики', level: 0, type: 'number' },
			monster: { name: 'Монстры', level: 0, type: 'number' },
			сonspirator: { name: 'Заговорщики', level: 0, type: 'number' },
			rogues: { name: 'Разбойники', level: 0, type: 'number' },
			squad: { name: 'Отряды', level: 0, type: 'number' },
		},
		type: 'list',
	}
};

/**
 * init
 */
HWMMap.init();
SettingsTab.init();
const notify = new Notify(GM_info.script.name, 'https://dcdn1.heroeswm.ru/i/gn_face.png');
const options = new GMSettings(scriptSettings);

/**
 * Process quest status
 * @param quest quest status
 * @param xhr xhr was used or not
 */
function questProgress(quest, xhr){
	const timerKey = 'timerMG';
	const map = ls.get('map');
	switch(quest.status){
		case 'new':
			if( xhr ){
				log.info('New quest availabe, reset MG timer');
				ls.set(timerKey, 0);
			}
			break;
		case 'old':
			if( xhr ){
				log.info('Old quest still in progress, reset MG timer');
				ls.set(timerKey, 0);
			}
			break;
		case 'done':
			notify.send({
				body: 'Задание успешно сдано\n' + quest.reward,
				tag: 'mercenary_quest',
				timeout: 15000,
				onclick: function(event){
					event.preventDefault();
					event.target.close();
				}
			});
			// refresh map data
			map.sectorMG = 0;
			ls.set('map', map);
			ls.set('mapTimestamp', Date.now());
			// set timer
			if( xhr ){
				log.info("Successful complete quest");
				ls.set(timerKey, Date.now() + 1000*60*quest.time);
			}
			break;
		case 'fail':
			notify.send({
				body: 'Задание было провалено',
				tag: 'mercenary_quest',
				timeout: 15000,
				onclick: function(event){
					event.preventDefault();
					event.target.close();
				}
			});
			// refresh map data
			map.sectorMG = 0;
			ls.set('map', map);
			ls.set('mapTimestamp', Date.now());
			// set timer
			if( xhr ){
				log.info("Quest was failed");
				ls.set(timerKey, Date.now() + 1000*60*quest.time);
			}
			break;
		case 'wait':
			if( xhr ){
				// correct timer if needed
				if( Math.abs(ls.get(timerKey) - ( Date.now() + 1000*60*quest.time ) ) > 1000*60 ){
					log.warn('Correcting MG timer');
					ls.set(timerKey, Date.now() + 1000*60*quest.time);
				}
			}
			break;
		default:
			log.error('Unknown status for mercenary quest');
	}
};

/**
 * Check if we can complete mercenary quest
 */
const map = ls.get('map');
const mgSectors = [2, 6, 16, 21];

if( options.data['mg_autocomplete'].value && map && !map.move && map.sectorMG == -1 && mgSectors.includes(map.sector) ){
	// check if already on page
	if( location.pathname.match(/mercenary_guild\.php/) ){
		questProgress(mercenaryQuestStatus(document.body.innerHTML), false);
	// or use xhr to complete
	} else {
		const xhr = runXHR('GET', 'mercenary_guild.php', true);
		xhr.onload = function(){
			// react only on successful request
			if( xhr.status == 200 && xhr.responseURL.match(/mercenary_guild/) ){
				questProgress(mercenaryQuestStatus(xhr.responseText), true);
			}
		}
	}
// fallback if dont have map data or we wait
} else if( location.pathname.match(/mercenary_guild\.php/) ){
	questProgress(mercenaryQuestStatus(document.body.innerHTML), false);
}

/**
 * delivere the cargo if possible
 */
const cargo = document.querySelector('a[href="/map.php?action=accept_merc_task3"]');
if( options.data['mg_autocargo'].value && cargo ){
	const xhr = runXHR('GET', 'map.php?action=accept_merc_task3', true);
	xhr.onload = function(){
		if( xhr.status == 200
			&& xhr.responseURL.match(/map\.php/) && xhr.responseText.match(/id="show_map"/)
			&& xhr.responseText.match(/href="\/map\.php\?action=accept_merc_task3"/) == null
		){
			notify.send({
				body: 'Груз успешно доставлен',
				tag: 'mercenary_cargo',
				timeout: 15000,
				onclick: function(event){
					event.preventDefault();
					parent.focus();
					window.focus();
					event.target.close();
				}
			});

			// update map info
			let m = ls.get('map');
			m.sectorMG = -1;
			ls.set('map', m);
			ls.set('mapTimestamp', Date.now());

			// hide cargo button
			const cargoTable = getParentByTagName(cargo, 'table', 1);
			if( cargoTable ){
				cargoTable.style.display = 'none';
			}

			log.info("The cargo was delivered");
		}
	}
}

/**
 * Fill settings tab
 */
const tab = SettingsTab.add('MG', 'ГН');
Object.keys(options.data).forEach(function(key){
	switch(options.data[key].type){
		case 'checkbox':
			const input = document.createElement('input');
			input.id = key;
			input.type = 'checkbox';
			input.checked = options.data[key].value;
			input.addEventListener('change', function(event){
				options.data[event.target.id].value = event.target.checked;
				options.data[event.target.id].save();
			});

			const label = document.createElement('label');
			label.htmlFor = input.id;
			label.textContent = options.data[key].name;

			tab.appendChild(input);
			tab.appendChild(label);
			tab.appendChild(document.createElement('br'));
			break;
		case 'list':
			tab.appendChild(document.createElement('hr'));
			const name = document.createElement('p');
			name.textContent = options.data[key].name;
			name.appendChild(document.createElement('br'));
			tab.appendChild(name);

			Object.keys(options.data[key].value).forEach(function(questType){
				const input = document.createElement('input');
				input.id = key + '_' + questType;
				input.dataset.quest = questType;
				input.type = options.data[key].value[questType].type;
				input.max = '50'; input.min = '0'; input.step = '1';
				input.value = options.data[key].value[questType].level;
				input.style.width = '45px';
				input.addEventListener('change', function(event){
					options.data[key].value[event.target.dataset.quest].level = event.target.value;
					options.data[key].save();
				});

				const label = document.createElement('label');
				label.htmlFor = input.id;
				label.textContent = options.data[key].value[questType].name;
				label.style.width = '65px';
				label.style.display = 'inline-block';

				tab.append(label,input,document.createElement('br'));
			});

			break;
		default:
			log.error('unknown option type: ' + options.data[key].type );
			break;
	}
});
